/*
 * GPUC
 * 
 * Copyright © 2008 Attila T. Áfra <attila.afra@gmail.com>
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "Common.hpp"
#include "Exception.hpp"
#include "Buffer.hpp"
#include "Stream.hpp"

/*------------------------------------------------------------------------------------------------*/

namespace GPUC
{
    void copy(const Stream& source, void* destination);
    void copy(const Stream& source, void* destination, const Rectangle& sourceRect);
    
    void copy(const void* source, Stream& destination);
    void copy(const void* source, Stream& destination, const Rectangle& destinationRect);
    
    void copy(const Buffer& source, void* destination);
    void copy(const Buffer& source, void* destination, size_t sourceOffset, size_t length);
    
    void copy(const void* source, Buffer& destination);
    void copy(const void* source, Buffer& destination, size_t destinationOffset, size_t length);
    
    void copy(const Buffer& source, Stream& destination);
    void copy(const Buffer& source, Stream& destination, size_t sourceOffset,
              const Rectangle& destinationRect);
    
    void copy(const Stream& source, Buffer& destination);
    void copy(const Stream& source, Buffer& destination, const Rectangle& sourceRect,
              size_t destinationOffset);
}
/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Stream& source, void* destination)
{
    GPUC_copyStreamToMemory(source.getObject(), destination);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Stream& source, void* destination, const GPUC::Rectangle& sourceRect)
{
    GPUC_partialCopyStreamToMemory(source.getObject(), destination, &sourceRect);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const void* source, GPUC::Stream& destination)
{
    GPUC_copyMemoryToStream(source, destination.getObject());
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const void* source, GPUC::Stream& destination,
                const GPUC::Rectangle& destinationRect)
{
    GPUC_partialCopyMemoryToStream(source, destination.getObject(), &destinationRect);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Buffer& source, void* destination)
{
    GPUC_copyBufferToMemory(source.getObject(), destination);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Buffer& source, void* destination, size_t sourceOffset, size_t length)
{
    GPUC_partialCopyBufferToMemory(source.getObject(), destination, sourceOffset, length);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const void* source, GPUC::Buffer& destination)
{
    GPUC_copyMemoryToBuffer(source, destination.getObject());
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const void* source, GPUC::Buffer& destination, size_t destinationOffset,
                size_t length)
{
    GPUC_partialCopyMemoryToBuffer(source, destination.getObject(), destinationOffset, length);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Buffer& source, GPUC::Stream& destination)
{
    GPUC_copyBufferToStream(source.getObject(), destination.getObject());
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Buffer& source, GPUC::Stream& destination, size_t sourceOffset,
                const GPUC::Rectangle& destinationRect)
{
    GPUC_partialCopyBufferToStream(source.getObject(), destination.getObject(), sourceOffset,
                                   &destinationRect);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Stream& source, GPUC::Buffer& destination)
{
    GPUC_copyStreamToBuffer(source.getObject(), destination.getObject());
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/

void GPUC::copy(const GPUC::Stream& source, GPUC::Buffer& destination,
                const GPUC::Rectangle& sourceRect, size_t destinationOffset)
{
    GPUC_partialCopyStreamToBuffer(source.getObject(), destination.getObject(), &sourceRect,
                                   destinationOffset);
    Internal::checkError();
}

/*------------------------------------------------------------------------------------------------*/
